/****

activequant - activestocks.eu

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


contact  : contact@activestocks.eu
homepage : http://www.activestocks.eu

****/
package org.activequant.data.retrieval.ib;

import org.activequant.core.domainmodel.InstrumentSpecification;
import org.activequant.core.domainmodel.marketdepth.MarketDepthEvent;
import org.activequant.core.types.TimeFrame;
import org.activequant.data.annotations.Vendor;
import org.activequant.data.retrieval.IMarketDepthEventSubscriptionSource;
import org.activequant.data.retrieval.ISubscription;
import org.activequant.data.retrieval.SubscriptionSourceBase;
import org.activequant.util.ib.IBTwsConnection;
import org.activequant.util.pattern.events.IEventListener;
import org.apache.log4j.Logger;


/**
* 
* TWS quote source. Requires a running tws connection. <br>
* <br>
* IBMarketDepthEventSource extends SubscriptionSourceBase&lt;MarketDepth&gt; implements IMarketDepthSubscriptionSource.<br>
* Holds the following associated variables:
* <ul>
* <li>connection(IBTwsConnection)</li>
* </ul>
* Holds the following inherited variables:
* <ul>
* <li>activeBackends(Map&lt;Topic, Subscription&gt;)</li>
* <li>activeSubscriptions(Queue&lt;SubscriptionDelegate&gt;)</li>
* </ul>
*/
@Vendor("IB")
public class IBMarketDepthEventSource extends SubscriptionSourceBase<MarketDepthEvent> implements IMarketDepthEventSubscriptionSource {
	/**
	 * private final IBTwsConnection connection;
	 */
	private final IBTwsConnection connection;
	
	protected final static Logger log = Logger.getLogger(IBMarketDepthEventSource.class);
	/**
	 * constructs an IBMarketDepthSource(extends SubscriptionSourceBase&lt;MarketDepth&gt; implements IMarketDepthSubscriptionSource) using the given monitor(IBTwsConnection)
	 * to set its associated connection(IBTwsConnection).
	 * @param monitor
	 */
	public IBMarketDepthEventSource(IBTwsConnection monitor) {
		super();
		connection = monitor; 
	}
	/**
	 * Returns/creates a ISubscription&lt;TradeIndication&gt; for the given spec(InstrumentSpecification) and TIMEFRAME_1_TICK.
	 */
	public ISubscription<MarketDepthEvent> subscribe(InstrumentSpecification spec) {
		return subscribe(spec, TimeFrame.TIMEFRAME_1_TICK);
	}
	/**
	 * MarketDepthSubscription extends Subscription. Holds the following associated variables:
	 * <ul>
	 * <li>spec(InstrumentSpecification)</li>
	 * <li>listener(IEventListener&lt;MarketDepth&gt;)</li>
	 * </ul>
	 * Holds the following inherited variables:
	 * <ul>
	 * <li>isActive(AtomicBoolean)</li>
	 * <li>refCount(AtomicInteger)</li>
	 * <li>instrument(InstrumentSpecification)</li>
	 * <li>event(Event&lt;MarketDepth&gt;)</li>
	 * </ul>
	 * @author Dimitar
	 *
	 */
	private class MarketDepthSubscription extends Subscription {
		/**
		 * private final InstrumentSpecification spec;
		 */
		private final InstrumentSpecification spec;
		/**
		 * constructs a MarketDepthSubscription(extends Subscription) using the given s(InstrumentSpecification) to set its associated spec(InstrumentSpecification)
		 * @param s
		 */
		MarketDepthSubscription(InstrumentSpecification s) {
			spec = s;
		}
		/**
		 * private final IEventListener&lt;MarketDepth&gt; listener = new IEventListener&lt;MarketDepth&gt;() {...}<br/>
		 * A listener that re-fires any event(MarketDepth)
		 */
		private final IEventListener<MarketDepthEvent> listener = new IEventListener<MarketDepthEvent>() {
			public void eventFired(MarketDepthEvent event) {
				fireEvent(event);
			}
		};
		/**
		 * Subscribes the associated listener(IEventListener&lt;MarketDepth&gt;) for real time market data from the connection(IBTwsConnection) for the associated spec(InstrumentSpecification)
		 */
		@Override
		protected void handleActivate() {
			connection.subscribeToMarketDepthStream(listener, spec);
		}
		/**
		 * Unsubscribes the associated listener(IEventListener&lt;MarketDepth&gt;) from listening to real time market data from the connection(IBTwsConnection) for the associated spec(InstrumentSpecification)
		 */
		@Override
		protected void handleCancel() {
			connection.unsubscribeFromMarketDepthStream(listener, spec);
		}
	}
	/**
	 * creates and returns a MarketDepthSubscription(extends Subscription) using the given spec(InstrumentSpecification) to set its associated spec(InstrumentSpecification).<br/>
	 * The given timeFrame(TimeFrame) is not used.
	 */
	@Override
	protected MarketDepthSubscription createSubscription(InstrumentSpecification spec, TimeFrame timeFrame) {
		return new MarketDepthSubscription(spec);
	}
}
